import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

class Result {
    public int sum = 0;
}

public class ThreadDemo21 {
    public static void main1(String[] args) throws InterruptedException {
        // 基于 CAS 实现的原子类
        AtomicInteger atomicInteger = new AtomicInteger(0);
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                // 相当于i++
                atomicInteger.getAndIncrement();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                atomicInteger.getAndIncrement();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(atomicInteger.get());
    }

    public static void mai2(String[] args) throws InterruptedException {
        Result result = new Result();

        // 创建一个线程, 执行1 + 2 + 3 ... +1000 的任务
        Thread t = new Thread(() -> {
            int count = 0;
            for (int i = 0; i < 1000; i++) {
                count += i;
            }
            synchronized (result) {
                result.sum = count;
                result.notify();
            }
        });

        t.start();

        synchronized (result) {
            while (result.sum == 0) {
                result.wait();
            }
            System.out.println(result.sum);
        }
    }

    public static void main3(String[] args) throws ExecutionException, InterruptedException {
        // 实现Callable接口, 创建一个任务
        // 相比于 Runnable , 在任务结束后可以返回一个参数
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int count = 0;
                for (int i = 0; i < 1000; i++) {
                    count += i;
                }
                return count;
            }
        };
        // 相当于一个小票, 可以得到任务执行后的结果
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        // 传给这个线程
        Thread t = new Thread(futureTask);
        // 启动线程
        t.start();

        // 这个get方法会阻塞等待线程结束
        int result = futureTask.get();
        System.out.println(result);
    }


    public static void main4(String[] args) {
        // 信号量
        // 初始化为 4， 表示有四个可用资源
        Semaphore semaphore = new Semaphore(4);

        // 创建 20 个线程，每个线程都尝试获取资源，sleep 1 秒后，释放资源
        for (int i = 0; i < 20; i++) {
            Thread t = new Thread(() -> {
                try {
                    System.out.println("申请资源");
                    semaphore.acquire();// 申请资源，原子的，申请不到资源会阻塞等待
                    System.out.println("我获取到资源了");
                    Thread.sleep(1000);
                    System.out.println("我释放资源了");
                    semaphore.release();// 释放资源，原子的
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 初始化 10 表示有 10 个任务需要完成
        CountDownLatch latch = new CountDownLatch(10);

        // 创建 10 个线程，来执行 10 个任务
        // 每个任务执行完毕，都调用 latch.countDown()
        // 使 CountDownLatch 内部的计时器自减
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(() -> {
                try {
                    Thread.sleep((long)(Math.random() * 1000));
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
        }

        latch.await();// 阻塞等待，当计数器为0时，停止等待
        System.out.println("比赛结束");
    }
}
